﻿using System;
using System.IO;
using System.IO.Packaging;
using System.Windows;
using System.Windows.Documents;
using System.Windows.Xps.Packaging;
using RG.Common.Const;
using RG.Common.WPF.Frames;
using Microsoft.Practices.Unity;
using RG.Common;

namespace RG.Common.WPF.Reporting
{
    public static class ReportUtil
    {

        public static void ToMAPI(this FixedDocumentSequence ReportDoc, string subject, string body)
        {
            var message = new MapiMailMessage(subject, body);

            var TempFileName = string.Format(@"{0}\{1}.xps", Path.GetTempPath(), subject.FixFileName());
            //проверим существует ли тот самый файл, если да то непорядок и мочим
            var fl = new FileInfo(TempFileName);
            if (fl.Exists) fl.Delete();

            var xpsDocument = new XpsDocument(TempFileName, FileAccess.ReadWrite);
            var xpsDocumentWriter = XpsDocument.CreateXpsDocumentWriter(xpsDocument);
            xpsDocumentWriter.Write(ReportDoc);
            xpsDocument.Close();

            message.Files.Add(TempFileName);
            message.ShowDialog();
        }

        private static Size GetPaperSize(ReportPaperSize reportPaperSize)
        {
            switch (reportPaperSize)
            {
                case ReportPaperSize.A4Portrait: return new Size(96 / 2.54 * 21, 96 / 2.54 * 28.7);
                case ReportPaperSize.A4Landscape: return new Size(96 / 2.54 * 28.7, 96 / 2.54 * 21);
                case ReportPaperSize.CustomProtonDp4205: return new Size(96 / 2.54 * 8, 96 / 2.54 * 5);
                default:
                    return new Size(96/2.54*21, 96/2.54*28.7);
            }
        }

        public static DocumentPaginator GetPaginator(this IReport report, ReportPaperSize reportPaperSize = ReportPaperSize.A4Portrait)
        {
            return new XpsReportPaginator(report.report,GetPaperSize(reportPaperSize));
        }

        public static FixedDocumentSequence WriteToPackage(this IReport report, string PackUriName, ReportPaperSize reportPaperSize = ReportPaperSize.A4Portrait )
        {
            var ms = new MemoryStream();
            var package = Package.Open(ms, FileMode.Create, FileAccess.ReadWrite);
            var doc = new XpsDocument(package, CompressionOption.SuperFast, PackUriName);
            PackageStore.AddPackage(new Uri(PackUriName), package);
            XpsDocument.CreateXpsDocumentWriter(doc).Write(report.GetPaginator(reportPaperSize));
            var fixedDoc = doc.GetFixedDocumentSequence();
            fixedDoc.DocumentPaginator.PageSize = GetPaperSize(reportPaperSize);
            return fixedDoc;
        }

        public static byte[] RenderReport<TFactory, TParams>(this IUnityContainer Cfg, TParams p, ReportPaperSize reportPaperSize = ReportPaperSize.A4Portrait /*bool isPortret = true*/)
            where TFactory : IReportfactoryBase<TParams>
        {
            var factory = Cfg.Resolve<TFactory>();
            factory.InitTemplateConstructor();
            var pages = factory.InitPages(p);
            if (pages.Count == 0)
                throw new ApplicationException("Пустой отчёт, нет данных");

            var uniq = DateTime.Now.Ticks;
            var docs = new System.Collections.Generic.List<FixedDocumentSequence>();

            for (int i = 0; i < pages.Count; i++)
            {
                var packUriName = string.Format("pack://tmp{0}-{1}.xps", uniq, i);
                var report = Cfg.CreateReport(pages[i]);
                docs.Add(report.WriteToPackage(packUriName, reportPaperSize));
            }

            var fixedDoc = (docs.Count == 1) ? docs[0] : DocMerger.SplitedDoc(docs);
            var result = fixedDoc.DocumentPaginator.ToStream().ToArray();

            for (int i = 0; i < pages.Count; i++)
            {
                var packUriName = string.Format("pack://tmp{0}-{1}.xps", uniq, i);
                PackageStore.RemovePackage(new Uri(packUriName));
            }

            return result;
        }
    }
}
